package service

import (
	"errors"
	"gitee.com/sansaniot/ssiot-core/msg/sms/sdk/ali"
	"strings"

	"gitee.com/sansaniot/ssiot-core/httpmvc/service"
	"gitee.com/sansaniot/ssiot-core/msg/sms"
	"gorm.io/gorm"

	"ssnotify/common/dto"
	"ssnotify/common/enums/sendway"
	"ssnotify/common/utils"
	"ssnotify/internal/notify/models"
	"ssnotify/internal/notify/models/command"
	"ssnotify/internal/notify/models/query"
)

type NotifyTemplate struct {
	notifyTemplate *models.NotifyTemplate
	service.Service
}

func (e *NotifyTemplate) SetNotifyTemplateModel(m *models.NotifyTemplate) *NotifyTemplate {
	e.notifyTemplate = m
	return e
}

func (e *NotifyTemplate) AddNotifyTemplate(req *command.NotifyTemplateAddReq) (one models.NotifyTemplate, err error) {
	req.Generate(&one)
	err = e.Orm.Transaction(func(tx *gorm.DB) error {
		e.notifyTemplate.Orm = tx
		// 短信模板特殊处理
		if err = e.smsTemp(req, &one); err != nil {
			return err
		}
		if er := e.notifyTemplate.Upsert(&one); er != nil {
			return er
		}
		return nil
	})
	return
}

func (e *NotifyTemplate) EditNotifyTemplate(req *command.NotifyTemplateModReq) (err error) {
	if req.Type == sendway.ShortMsg.Get().SendType {
		return
	}
	if err = e.notifyTemplate.FindOne(e.notifyTemplate, dto.MakeCondition(query.NotifyTemplateGetReq{Id: req.Id})); err != nil {
		return
	}
	req.Generate(e.notifyTemplate)
	err = e.notifyTemplate.Mod(e.notifyTemplate)
	return
}

func (e *NotifyTemplate) DeleteNotifyTemplate(c *command.NotifyTemplateDelReq) (err error) {
	notifyTemplates := make([]models.NotifyTemplate, 0)
	if err = e.notifyTemplate.FindList(&notifyTemplates, dto.MakeCondition(query.NotifyTemplateGetReq{IdIn: c.Ids})); err != nil {
		return
	}
	upsertTemps := make([]models.NotifyTemplate, 0)
	delIds := make([]string, 0)
	for _, v := range notifyTemplates {
		if v.Type == sendway.ShortMsg.Get().SendType {
			//if er := sms.DeleteTemplate(v.Id); er != nil {
			//	e.Log.Error(er)
			//}
			// 短信模板,按租户删
			tmpCreatorIds := strings.Split(v.CreatorId, ",")
			tmpAgencyIds := strings.Split(v.AgencyId, ",")
			utils.RemoveAll(&tmpCreatorIds, []string{c.UserId})
			utils.RemoveAll(&tmpAgencyIds, []string{c.AgencyId})
			if len(tmpAgencyIds) == 0 {
				delIds = append(delIds, v.Id)
			} else {
				v.CreatorId = strings.Join(tmpCreatorIds, ",")
				v.AgencyId = strings.Join(tmpAgencyIds, ",")
				upsertTemps = append(upsertTemps, v)
			}
		} else {
			delIds = append(delIds, v.Id)
		}
	}
	err = e.Orm.Transaction(func(tx *gorm.DB) error {
		e.notifyTemplate.Orm = tx
		if len(upsertTemps) > 0 {
			if err = e.notifyTemplate.Upsert(&upsertTemps); err != nil {
				return err
			}
		}
		if len(delIds) > 0 {
			if err = e.notifyTemplate.Delete(e.notifyTemplate, dto.MakeCondition(query.NotifyTemplateGetReq{IdIn: delIds})); err != nil {
				return err
			}
		}
		return nil
	})
	return
}

func (e *NotifyTemplate) smsTemp(req *command.NotifyTemplateAddReq, one *models.NotifyTemplate) (err error) {
	if req.Type != sendway.ShortMsg.Get().SendType || len(one.Id) == 0 {
		return
	}
	// 短信模板的agencyId处理
	nt := models.NotifyTemplate{}
	if err = e.notifyTemplate.FindOne(&nt, dto.MakeCondition(query.NotifyTemplateGetReq{Id: one.Id})); err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		return
	}
	if len(nt.Id) > 0 {
		// 已存在，则合并当前租户id
		tmpCreatorIds := strings.Split(nt.CreatorId, ",")
		tmpAgencyIds := strings.Split(nt.AgencyId, ",")
		if !utils.StrIn(one.CreatorId, tmpCreatorIds) {
			tmpCreatorIds = append(tmpCreatorIds, one.CreatorId)
		}
		if !utils.StrIn(one.AgencyId, tmpAgencyIds) {
			tmpAgencyIds = append(tmpAgencyIds, one.AgencyId)
		}
		one.CreatorId = strings.Join(tmpCreatorIds, ",")
		one.AgencyId = strings.Join(tmpAgencyIds, ",")
	}
	// 是否需要提交到阿里云短信
	addFlag := true
	list := make([]ali.Template, 0)
	if err = sms.GetTemplateList(&list); err != nil {
		return err
	}
	for _, aliTemp := range list {
		if aliTemp.TemplateCode != nil && *aliTemp.TemplateCode == one.Id {
			addFlag = false
			break
		}
	}
	if addFlag {
		if err = sms.AddTemplate(&ali.Template{
			TemplateName:    &req.Name,
			TemplateContent: &req.Content,
		}); err != nil {
			return err
		}
	}
	return
}
